Android jar包导出资源的问题

有的时候我们需要导出自己的项目,jar包,或者其他资源供第三方使用,这里介绍一下。

纯java代码

eclipse export导出jar包,只包含相应的.java文件就好了。

有资源的项目

可能有activity,fragment等ui,打成包让别人调用,这时候只打java代码成class是调用不了的,会报错,这时候就要把资源文件,so库,lib依赖等都要一起导出,供第三方使用。但是资源id会找不到
解决方式是通过反射相关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class MResource {  
public static int getIdByName(Context context, String className, String name) {
String packageName = context.getPackageName();
Class r = null;
int id = 0;
try {
r = Class.forName(packageName + ".R");

Class[] classes = r.getClasses();
Class desireClass = null;

for (int i = 0; i < classes.length; ++i) {
if (classes[i].getName().split("\\$")[1].equals(className)) {
desireClass = classes[i];
break;
}
}

if (desireClass != null)
id = desireClass.getField(name).getInt(desireClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}

return id;
}
}

调用方式也要修改

1
2
setContentView(MResource.getIdByName(BookMiguListMusicActivity.this, "layout",
"activity_book_migu_music_list"));

aar包导出

随着as的广泛使用,aar包的导出方式比较流行。

.jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有res中的文件。 .aar:包含所有资源,class以及res资源文件全部包含

如果你只是一个简单的类库那么使用生成的.jar文件即可;如果你的是一个UI库,包含一些自己写的控件布局文件以及字体等资源文件那么就只能使用.aar文件。

要输出 aar 文件,必须将 Module 配置为 library,在 gradle 文件中如下:

输出 aar : apply plugin: ‘com.android.library’; 输出 apk :apply plugin: ‘com.android.application’。
将 Module 配置为 library 后,构建输出一个 aar 文件,根据渠道和 BuildType 的不同,在相应的目录下可以找到。比如对 BuildType 为 debug 的配置,输出为:[ModuleName]/build/outputs/aar/[ModuleName]-debug.aar。一份 aar 文件其实就是一份 zip 包,和 jar 不同的是,它将一些资源文件、第三方库文件、so 文件等等都打包在内,而代码文件编译后压缩在在 classes.jar 中。

导入 aar 的方式引用

这种方式比较简单,打开 Project Structure,添加一个新 Module,然后选择 Import .JAR or .AAR Package 的方式导入.导入后,在你的工程下面,会生成一个文件夹,里面是 aar 文件以及 Android Studio 的配置文件。

接着可以在 gradle 中配置依赖了,其他 Module 可以引用这个 Module 了,依赖方式使用 compile project 的方式即可。

缺点:被依赖的 aar 无法 F3 跟进去,无法看到资源文件内容以及目录层级等等缺陷。

使用配置依赖的方式引用

gradle 其实还有另一种依赖可以引用 aar:

1
compile(name: 'xxx', ext: 'aar')

首先需要将 aar 文件放入引用 Module 的 libs 目录下,和一般的 jar 文件类似。然后在 gradle 配置文件中把 libs 目录加入依赖:

1
2
3
4
5
repositories {
flatDir {
dirs 'libs'
}
}

接着在 gradle 的依赖配置中加入 compile(name: ‘xxx’, ext: ‘aar’) 这一句,依赖即可关联完毕。构建一下工程,在 Module 的 build/intermediates/exploded-aar 目录下,可以看到有一些临时文件生成
看起来完全是引用 aar 的解压版本。Android Studio 安装反编译插件后,可以通过 F3 跟进到 class 文件里面,如果你有被依赖 Module 的源代码的话,还可以 Attach Source 关联源代码查看。另外,可以很方便的查看 aar 中的资源文件。

另外,这种依赖方式更新 aar 后,生成的临时文件也会随之变动,不用担心改动不同步的问题。

总结

综上,介绍了 aar 文件的生成方式,以及两种 aar 依赖的方式,经过实战检验,第二种通过配置 gradle 依赖的方式简单易用,只需一行代码即可搞定。